﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace NWebMock
{
    public class HttpResponseWrapper : IHttpResponse
    {
        #region Constructors

        public HttpResponseWrapper(HttpResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            this.innerResponse = response;
        }

        #endregion

        #region Fields

        private IHttpCachePolicy innerCache = null;
        private IHttpCookieCollection innerCookies = null;
        private HttpResponse innerResponse = null;

        #endregion

        #region Properties

        public bool Buffer { get { return this.innerResponse.Buffer; } set { this.innerResponse.Buffer = value; } }

        public bool BufferOutput { get { return this.innerResponse.BufferOutput; } set { this.innerResponse.BufferOutput = value; } }

        public IHttpCachePolicy Cache
        {
            get
            {
                if (this.innerCache != null)
                {
                    return this.innerCache;
                }

                if (this.innerResponse.Cache != null)
                {
                    this.innerCache = new HttpCachePolicyWrapper(this.innerResponse.Cache);
                }

                return this.innerCache;
            }
        }

        public string CacheControl { get { return this.innerResponse.CacheControl; } set { this.innerResponse.CacheControl = value; } }

        public string Charset { get { return this.innerResponse.Charset; } set { this.innerResponse.Charset = value; } }

        public Encoding ContentEncoding { get { return this.innerResponse.ContentEncoding; } set { this.innerResponse.ContentEncoding = value; } }

        public string ContentType { get { return this.innerResponse.ContentType; } set { this.innerResponse.ContentType = value; } }

        public IHttpCookieCollection Cookies
        {
            get
            {
                if (this.innerCookies != null)
                {
                    return this.innerCookies;
                }

                if (this.innerResponse.Cookies != null)
                {
                    this.innerCookies = new HttpCookieCollectionWrapper(this.innerResponse.Cookies);
                }

                return this.innerCookies;
            }
        }

        public int Expires { get { return this.innerResponse.Expires; } set { this.innerResponse.Expires = value; } }

        public DateTime ExpiresAbsolute { get { return this.innerResponse.ExpiresAbsolute; } set { this.innerResponse.ExpiresAbsolute = value; } }

        public Stream Filter { get { return this.innerResponse.Filter; } set { this.innerResponse.Filter = value; } }

        public Encoding HeaderEncoding { get { return this.innerResponse.HeaderEncoding; } set { this.innerResponse.HeaderEncoding = value; } }

        public NameValueCollection Headers { get { return this.innerResponse.Headers; } }

        public bool IsClientConnected { get { return this.innerResponse.IsClientConnected; } }

        public bool IsRequestBeingRedirected { get { return this.innerResponse.IsRequestBeingRedirected; } }

        public TextWriter Output { get { return this.innerResponse.Output; } }

        public Stream OutputStream { get { return this.innerResponse.OutputStream; } }

        public string RedirectLocation { get { return this.innerResponse.RedirectLocation; } set { this.innerResponse.RedirectLocation = value; } }

        public string Status { get { return this.innerResponse.Status; } set { this.innerResponse.Status = value; } }

        public int StatusCode { get { return this.innerResponse.StatusCode; } set { this.innerResponse.StatusCode = value; } }

        public string StatusDescription { get { return this.innerResponse.StatusDescription; } set { this.innerResponse.StatusDescription = value; } }

        public int SubStatusCode { get { return this.innerResponse.SubStatusCode; } set { this.innerResponse.SubStatusCode = value; } }

        public bool SuppressContent { get { return this.innerResponse.SuppressContent; } set { this.innerResponse.SuppressContent = value; } }

        public bool TrySkipIisCustomErrors { get { return this.innerResponse.TrySkipIisCustomErrors; } set { this.innerResponse.TrySkipIisCustomErrors = value; } }

        #endregion

        #region Methods

        public void AddCacheDependency(params CacheDependency[] dependencies)
        {
            this.innerResponse.AddCacheDependency(dependencies);
        }

        public void AddCacheItemDependencies(ArrayList cacheKeys)
        {
            this.innerResponse.AddCacheItemDependencies(cacheKeys);
        }

        public void AddCacheItemDependencies(string[] cacheKeys)
        {
            this.innerResponse.AddCacheItemDependencies(cacheKeys);
        }

        public void AddCacheItemDependency(string cacheKey)
        {
            this.innerResponse.AddCacheItemDependency(cacheKey);
        }

        public void AddFileDependencies(ArrayList filenames)
        {
            this.innerResponse.AddFileDependencies(filenames);
        }

        public void AddFileDependencies(string[] filenames)
        {
            this.innerResponse.AddFileDependencies(filenames);
        }

        public void AddFileDependency(string filename)
        {
            this.innerResponse.AddFileDependency(filename);
        }

        public void AddHeader(string name, string value)
        {
            this.innerResponse.AddHeader(name, value);
        }

        public void AppendCookie(HttpCookie cookie)
        {
            this.innerResponse.AppendCookie(cookie);
        }

        public void AppendHeader(string name, string value)
        {
            this.innerResponse.AppendHeader(name, value);
        }

        public void AppendToLog(string param)
        {
            this.innerResponse.AppendToLog(param);
        }

        public string ApplyAppPathModifier(string virtualPath)
        {
            return this.innerResponse.ApplyAppPathModifier(virtualPath);
        }

        public void BinaryWrite(byte[] buffer)
        {
            this.innerResponse.BinaryWrite(buffer);
        }

        public void Clear()
        {
            this.innerResponse.Clear();
        }

        public void ClearContent()
        {
            this.innerResponse.ClearContent();
        }

        public void ClearHeaders()
        {
            this.innerResponse.ClearHeaders();
        }

        public void Close()
        {
            this.innerResponse.Close();
        }

        public void DisableKernelCache()
        {
            this.innerResponse.DisableKernelCache();
        }

        public void End()
        {
            this.innerResponse.End();
        }

        public void Flush()
        {
            this.innerResponse.Flush();
        }

        public void Pics(string value)
        {
            this.innerResponse.Pics(value);
        }

        public void Redirect(string url)
        {
            this.innerResponse.Redirect(url);
        }

        public void Redirect(string url, bool endResponse)
        {
            this.innerResponse.Redirect(url, endResponse);
        }

        public void SetCookie(HttpCookie cookie)
        {
            this.innerResponse.SetCookie(cookie);
        }

        public void TransmitFile(string filename)
        {
            this.innerResponse.TransmitFile(filename);
        }

        public void TransmitFile(string filename, long offset, long length)
        {
            this.innerResponse.TransmitFile(filename, offset, length);
        }

        public void Write(char ch)
        {
            this.innerResponse.Write(ch);
        }

        public void Write(object obj)
        {
            this.innerResponse.Write(obj);
        }

        public void Write(string s)
        {
            this.innerResponse.Write(s);
        }

        public void Write(char[] buffer, int index, int count)
        {
            this.innerResponse.Write(buffer, index, count);
        }

        public void WriteFile(string filename)
        {
            this.innerResponse.WriteFile(filename);
        }

        public void WriteFile(string filename, bool readIntoMemory)
        {
            this.innerResponse.WriteFile(filename, readIntoMemory);
        }

        public void WriteFile(IntPtr fileHandle, long offset, long size)
        {
            this.innerResponse.WriteFile(fileHandle, offset, size);
        }

        public void WriteFile(string filename, long offset, long size)
        {
            this.innerResponse.WriteFile(filename, offset, size);
        }

        public void WriteSubstitution(HttpResponseSubstitutionCallback callback)
        {
            this.innerResponse.WriteSubstitution(callback);
        }

        #endregion
    }
}
